package com.adee.java;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Random;

/*
基本类型
整数默认为int，小数默认为double
 */
public class Test004_BasicType {
    public static void main(String[] args) {
        short s0 = (short)9999999; // 字面量常量可自动进行强制类型转换，但超出范围则需要手动强制类型转换
        short s1 = 9999;
        // 参与计算时，整数默认转为int，小数默认转为double，然后再参与计算，计算结果也是int或double类型
        short s2 = (short)((short)(s1 + 10) + 50);
        System.out.println("s0:" + s0 + ", s1:" + s1 + ", s2:" + s2);

        // char类型为无符号类型，类型转换必须强制转换
        byte b1 = -2;
        char c1 = (char)b1; // 不能自动类型转换

        // char扩展为int按无符号处理（高位补0）， short扩展为int按有符号处理（高位补short数值符号位）
        short s5 = -8;
        char c5 = (char)s5;
        System.out.println((int)s5); // -8
        System.out.println((int)c5); // 65528
        // byte分别扩展为char和short
        short s6 = b1; // 类型扩展（除了和char有关的，其余都是有符号扩展），类型扩大会隐式转换
        char c6 = (char)b1; // byte -> char 按有符号扩展（高位补符号位）
        System.out.println((int)s6); // -2
        System.out.println((int)c6); // 65534

        /*
        * - - -	符号位	指数符号位	指数位	尾数位	总计
        float	1	    1	        7	    23	    32
        double	1	    1	        10	    52	    64
        * 此处以float类6.5为例，讲解浮点型的储存方式。
        （1）将6.5整数部分6转化为二进制形式，得110；
        （2）将6.5小数部分0.5转化为二进制形式，得0.1（求小数二进制的方法自查）；
        （3）整合上述步骤，得6.5的二进制形式为110.1；
        （4）将110.1转化为科学计数法形式，得1.101 x 22，得符号位0，指数符号位0，指数位2，转化二进制形式为10，尾数位101；
        * */
        int i1 = 30000000;
        float f1 = i1;
        float f2 = f1 + 1;
        float f3 = f1 + 2;
        System.out.println("Float.MAX_VALUE:" + (Float.MAX_VALUE - 1)); // 3.4028235E38
        System.out.println("f1:" + f1); // 3.0E7
        System.out.println("f2:" + f2); // 3.0E7
        System.out.println("30000000==30000001:" + (f1 == f1 + 1)); // true，超出精度范围部分被忽略，值比较精度范围之内的部分
        System.out.println("30000000==30000001:" + (f1 == f2)); // true
        System.out.println("30000000==30000002:" + (f1 == f1 + 2)); // false
        System.out.println("f2 - f1:" + (f2 - f1)); // 0.0
        System.out.println("f3 - f1:" + (f3 - f1)); // 2.0
        /*
         * 二进制逻辑表示： 1110010011100001110000000
         * 浮点定义表示：1.110010011100001110000000 * Math.pow(2,24)
         * 尾数部分长度为24，超过23，丢弃低位1位，为0，因此不影响原数值
         * */
        System.out.println(Integer.toString(i1, 2));       //  1110010011100001110000000
        System.out.println(Integer.toString((int) f1, 2)); //  1110010011100001110000000
        /*
         * 二进制逻辑表示： 1110010011100001110000001
         * 浮点定义表示：1.110010011100001110000001 * Math.pow(2,24)
         * 尾数部分长度为24，超过23，丢弃低位1位，为1，影响原数值，丢弃后变为1.110010011100001110000000 * Math.pow(2,23)，
         * 还原后就变为1110010011100001110000000
         * */
        System.out.println(Integer.toString(i1 + 1, 2));     //  1110010011100001110000001
        System.out.println(Integer.toString((int) (f1+1), 2));  //  1110010011100001110000000
        /*
         * 二进制逻辑表示： 1110010011100001110000010
         * 浮点定义表示：1.110010011100001110000010 * Math.pow(2,24)
         * 尾数部分长度为24，超过23，丢弃低位1位，为0，不影响原数值
         * */
        System.out.println(Integer.toString(i1+2, 2));      // 1110010011100001110000000
        System.out.println(Integer.toString((int) (f1+2), 2)); // 1110010011100001110000000

        // +号运算规则从左向右，每二元做一次运算，除非遇到二元其一为String，否则不转为StringBuilder
        // String加号编译后转为StringBuilder，从左到右依次处理，若有相邻的字符串字面量，编译器会合并为一个字面量
        String str1 = "";
        System.out.println('a'); // a
        System.out.println('a'+1); // 98，char类型参与运算时，先转为int类型，再和1相加
        System.out.println("hello"+'a'+1); // helloa1
        System.out.println('a'+1+"hello"); // 98hello
        System.out.println("5+5="+5+5); // 5+5=55
        System.out.println(5+5+"=5+5"); // 10=5+5

        // String.intern()
        int cnt1 = new Random().nextInt(100);
        int cnt2 = new Random().nextInt(100);
        String str2 = "Hell";
        String str3;
        if(cnt1 > cnt2) {
            str3 = str2 + "o";
        } else {
            str3 = str2 + "y";
        }
        new String("a");
        System.out.println(str3.intern() == "Hello");
        System.out.println(str3.intern() == "Helly");

        ArrayList list;
        LinkedList list1;
        HashMap map;

        int i8 = 5;
        /*
         * 后加加运算符实现原理为隐式临时变量，后加加出现一次，则创建一个临时变量，如下语句逻辑等价于：
         * // i8++每出现一次，等价于 int temp1 = i8; i8 += 1; 这两行代码
         * int temp1 = i8; // temp1==5
         * i8 += 1; // i8==6
         * // 此时临时代码变为：int i9 = temp1 + i8++ + i8++;
         * int temp2 = i8; // temp2==6
         * i8 += 1; // i8==7
         * // 此时临时代码变为：int i9 = temp1 + temp2 + i8++;
         * int temp3 = i8; // temp3==7
         * i8 += 1; // i8==8
         * // 此时临时代码变为：int i9 = temp1 + temp2 + temp3;，即 int i9 = 5 + 6 + 7;
         *
         * */
        int i9 = i8++ + i8++ + i8++;
        System.out.println("i9:" + i9 + ", i8:" + i8); // i9:18, i8:8
        int i10 = 5;
        i10 *= (i10=2);
        System.out.println("i10: " + i10); // 10

    }
}




